/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.inspur.edp.jittojava.core.manager;

import com.inspur.edp.caf.generator.compileunit.CompileUnitGenerator;
import com.inspur.edp.caf.generator.module.ModuleGenerator;
import com.inspur.edp.jittojava.context.JitContext;
import com.inspur.edp.jittojava.context.entity.JitCompilerConfigration;
import com.inspur.edp.jittojava.core.CommonServiceCore;
import com.inspur.edp.jittojava.core.JitCompilerHelper;
import com.inspur.edp.jittojava.core.JitUtils;
import com.inspur.edp.jittojava.core.persistence.RepositoryFactory;
import com.inspur.edp.jittojava.spi.AfterGeneratorAction;
import com.inspur.edp.jittojava.spi.JitAction;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.GspProject;
import com.inspur.edp.lcm.metadata.api.entity.MetadataProject;
import com.inspur.edp.lcm.metadata.api.mvnEntity.MavenPackageRefs;
import com.inspur.edp.lcm.metadata.api.service.MdpkgService;
import com.inspur.edp.lcm.metadata.common.FileServiceImp;
import com.inspur.edp.lcm.metadata.common.Utils;
import com.inspur.edp.lcm.metadata.core.GspProjectCoreService;
import com.inspur.edp.lcm.metadata.core.MavenUtilsCore;
import com.inspur.edp.lcm.metadata.core.MetadataCoreManager;
import com.inspur.edp.lcm.metadata.core.MetadataProjectCoreService;
import com.inspur.lcm.metadata.logging.LoggerDisruptorQueue;
import io.iec.edp.caf.boot.context.CAFContext;
import io.iec.edp.caf.common.environment.EnvironmentUtil;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GeneratorManager {
    private static final Logger log = LoggerFactory.getLogger(GeneratorManager.class);

    MetadataProjectCoreService metadataProjectCoreService = new MetadataProjectCoreService();
    GspProjectCoreService gspProjectCoreService = new GspProjectCoreService();
    MavenUtilsCore mavenUtilsCore = new MavenUtilsCore();
    MetadataCoreManager metadataCoreManager = new MetadataCoreManager();
    FileServiceImp fileService = new FileServiceImp();
    CommonServiceCore commonServiceCore = new CommonServiceCore();
    MdpkgService mdpkgService = SpringBeanUtils.getBean(MdpkgService.class);

    protected List<GspMetadata> metadataList = new ArrayList<>();
    protected JitContext jitContext;
    protected final String fixedPath = "src/main/java";
    protected boolean isModelExist;
    protected boolean isOldProject = false;
    protected Model model;

    protected String archetypePath;
    protected String archetypeTarget;
    protected String archetypeArtifactId;
    protected String refModule;

    public void generate(String absolutePath, String mavenPath) throws Exception {
        beforeGenerate(absolutePath);
        try {
            //构建生成上下文
            jitContext = buildJitContext(absolutePath);
            //创建maven工程与模块
            createMavenProject(jitContext, mavenPath);
            //生成源代码
            generateCode(jitContext);
            //生成后事件
            afterGenerate(absolutePath);
        } finally {
            isOldProject = false;
        }
    }

    public void generateApi(String absolutePath, String mavenPath) throws Exception {
        try {
            //构建生成上下文
            jitContext = buildJitContext(absolutePath);
            //创建maven工程与模块
            createMavenProject(jitContext, mavenPath);
            //生成api代码
            generateApi(jitContext);
        } finally {
        }
    }

    protected void generateApi(JitContext jitContext) {
        //获取所有注册的Jit类型
        List<JitCompilerConfigration> compilerTypeList = JitCompilerHelper.getInstance().getCompilerTypeList();
        generateApiCode(compilerTypeList, jitContext);
    }

    protected void generateCode(JitContext jitContext) {
        //获取所有注册的Jit类型
        List<JitCompilerConfigration> compilerTypeList = JitCompilerHelper.getInstance().getCompilerTypeList();

        generateApiCode(compilerTypeList, jitContext);

        generateCoreCode(compilerTypeList, jitContext);
    }

    protected void generateApiCode(List<JitCompilerConfigration> compilerTypeList, JitContext jitContext) {
        String loStr = "开始：生成API代码";
        log.info(loStr);
        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
        //组织API生成的上下文
        generateApiCode(compilerTypeList);
        //生成API代码
        jitContext.getApiModuleGenerator().initialize();
        jitContext.getApiModuleGenerator().generate();
        loStr = "完成：生成API代码";
        log.info(loStr);
        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
    }

    protected void generateApiCode(List<JitCompilerConfigration> compilerTypeList) {
        //组织api代码生成路径
        setPath("api");
        metadataList.forEach(item -> {
            for (JitCompilerConfigration config : compilerTypeList) {
                if (item.getHeader().getType().equals(config.getTypeCode())) {
                    // 获取元数据实体传给各元数据编译器
                    if (item.getHeader().getFileName() == null) {
                        throw new IllegalArgumentException("路径" + item.getRelativePath() + "下有元数据FileName属性为空，请检查");
                    }
                    GspMetadata metadata = metadataCoreManager.loadMetadata(item.getHeader().getFileName(), item.getRelativePath());
                    if (metadata == null) {
                        String loStr = "没有拿到元数据";
                        log.info(loStr);
                        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
                    }

                    jitContext.setMetadata(metadata);

                    if (jitContext.getMetadataCache(metadata.getHeader().getId()) == null) {
                        jitContext.setMetadataCache(metadata.getHeader().getId(), metadata);
                    }

                    JitAction jitAction = JitCompilerHelper.getInstance().getManager(item.getHeader().getType());
                    if (jitAction != null) {
                        String loStr = "jitInfo " + jitAction.toString();
                        log.info(loStr);
                        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
                    }
                    if (jitAction != null) {
                        jitAction.generateApi(jitContext);
                    }
                }
            }
        });
    }

    protected void generateCoreCode(List<JitCompilerConfigration> compilerTypeList, JitContext jitContext) {
        String loStr = "开始：生成CORE代码";
        log.info(loStr);
        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
        //组织CORE生成的上下文
        generateCoreCode(compilerTypeList);
        //生成CORE代码
        jitContext.getCoreModuleGenerator().initialize();
        jitContext.getCoreModuleGenerator().generate();
        loStr = "完成：生成CORE代码";
        log.info(loStr);
        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
    }

    protected void generateCoreCode(List<JitCompilerConfigration> compilerTypeList) {
        //组织api代码生成路径
        setPath("core");
        metadataList.forEach(item -> {
            for (JitCompilerConfigration config : compilerTypeList) {
                if (item.getHeader().getType().equals(config.getTypeCode())) {
                    // 获取元数据实体传给各元数据编译器
                    GspMetadata metadata = metadataCoreManager.loadMetadata(item.getHeader().getFileName(), item.getRelativePath());
                    jitContext.setMetadata(metadata);
                    if (jitContext.getMetadataCache(metadata.getHeader().getId()) == null) {
                        jitContext.setMetadataCache(metadata.getHeader().getId(), metadata);
                    }
                    JitAction jitAction = JitCompilerHelper.getInstance().getManager(item.getHeader().getType());
                    if (jitAction != null) {
                        jitAction.generateCore(jitContext);
                    }
                }
            }
        });
    }

    protected void afterGenerate(String absolutePath) {
        String loStr = "开始：生成后事件";
        log.info(loStr);
        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
        List<String> metadataTypes = new ArrayList<>();
        List<GspMetadata> metadataList = metadataCoreManager.getMetadataList(absolutePath);
        if (metadataList == null || metadataList.size() <= 0) {
            return;
        }
        metadataTypes.add("CommonExtend");
        metadataList.forEach(item -> {
            if (!metadataTypes.contains(item.getHeader().getType())) {
                metadataTypes.add(item.getHeader().getType());
            }
        });
        metadataTypes.forEach(type -> {
            AfterGeneratorAction action = JitCompilerHelper.getInstance().getAfterActionManager(type);
            if (action != null) {
                action.afterGenerator(absolutePath);
            }
        });

        ArrayList<String> types = new ArrayList<>();
        types.add("api_src");
        types.add("metadata");
        metadataProjectCoreService.setSourceDataModifiedTime(absolutePath, types);
        loStr = "完成：生成后事件";
        log.info(loStr);
        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
    }

    protected void beforeGenerate(String absolutePath) {
        SpringBeanUtils.getBean(MdpkgService.class).restore(absolutePath, false);
    }

    protected void setPath(String flag) {
        String javaProjectPath = fileService.getCombinePath(jitContext.getGspProjectpath(), Utils.getJavaProjectPath());

        String artifactID;
        String dir;
        if (isOldProject) {
            artifactID = getArtifactId(jitContext);
            dir = artifactID + "-" + flag;
        } else {
            dir = flag;
            artifactID = Utils.getMavenProName();
        }
        String codePath = Paths.get(javaProjectPath).resolve(artifactID).resolve(dir).resolve(fixedPath).toString();
        String resPath = Paths.get(javaProjectPath).resolve(artifactID).resolve(dir).resolve(Utils.getResourcesPath()).toString();
        jitContext.setCodePath(codePath);
        jitContext.setResourcePath(resPath);
    }

    protected JitContext buildJitContext(String absolutePath) {
        String loStr = "开始：构建生成上下文";
        log.info(loStr);
        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
        //构建上下文内容，此处需要确定是否包含工程信息，元数据信息等
        JitContext context = new JitContext();
        try {
            context.setGspProjectpath(absolutePath);
            Utils.setMetadataPath(absolutePath);
            GspProject gspProjectInfo = gspProjectCoreService.getGspProjectInfo(absolutePath);
            MetadataProject metadataProjectInfo = metadataProjectCoreService.getMetadataProjInfo(absolutePath);
            context.setMetadataProjectInfo(metadataProjectInfo);
            context.setGspProjectInfo(gspProjectInfo);
            context.setApiModuleGenerator(new ModuleGenerator() {
                @Override
                protected ArrayList<CompileUnitGenerator> getCompileUnitGenrators() {
                    return null;
                }
            });
            context.setCoreModuleGenerator(new ModuleGenerator() {
                @Override
                protected ArrayList<CompileUnitGenerator> getCompileUnitGenrators() {
                    return null;
                }
            });
            MetadataCoreManager metadataCoreManager = new MetadataCoreManager();
            this.metadataList = metadataCoreManager.getMetadataList(absolutePath);
//            MetadataDevCacheManager.setMetadataListInProjectCache(new File(absolutePath).getName(), this.metadataList);
//            List<String> refProjPaths = new ArrayList<>();
//            metadataProjectCoreService.getRefProjPaths(absolutePath, refProjPaths);
//            for (String projPath : refProjPaths) {
//                List<GspMetadata> metadataList = metadataCoreManager.getMetadataList(projPath);
//                MetadataDevCacheManager.setMetadataListInProjectCache(new File(projPath).getName(), metadataList);
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        loStr = "结束：构建生成上下文";
        log.info(loStr);
        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
        return context;
    }

    protected void createMavenProject(JitContext jitContext, String mavenPath) throws Exception {
        String loStr = "开始：创建maven工程";
        log.info(loStr);
        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());

        // 模板
        installArchetype(mavenPath);

        // 判断maven模板是否生成
        String javaProjectPath = fileService.getCombinePath(jitContext.getGspProjectpath(), Utils.getJavaProjectPath());
        isModelExist = isModelExist(javaProjectPath);

        // 生成模板工程的过程中如果同名工程存在,maven会报错.
        if (!isModelExist) {
            generateArchetype(javaProjectPath, mavenPath);
        } else {
            // 清理api和core
            clearCode(javaProjectPath);
        }
        updateEdpParentVersion(javaProjectPath);

        updateModuleRefs(javaProjectPath, mavenPath);

        loStr = "完成：创建maven工程";
        log.info(loStr);
        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
    }

    protected void updateModuleRefs(String javaProjectPath, String mavenPath) {
        String refPomPath = javaProjectPath + File.separator + "code" + File.separator + refModule + File.separator + Utils.getPomFile();
        String metadataPath = javaProjectPath.substring(0, javaProjectPath.length() - 4) + "metadata";
        if (fileService.isFileExist(refPomPath)) {
            MetadataProject metadataProject = metadataCoreManager.getMetadataProjInfo(metadataPath);
            if (metadataProject.getMavenPackageRefs() != null && metadataProject.getMavenPackageRefs().size() > 0) {
                final List<MavenPackageRefs> generationMavenPackageRefs = getGenerationMavenPackageRefs(metadataProject, mavenPath);
                RepositoryFactory.getInstance().getGenerateRepository().updateModuleRefs(refPomPath, generationMavenPackageRefs, true);
            }
        }
    }

    protected List<MavenPackageRefs> getGenerationMavenPackageRefs(MetadataProject metadataProject, String mavenPath) {
        return metadataProject.getMavenPackageRefs();
    }

    protected void updateEdpParentVersion(String javaProjectPath) throws IOException {
        String pomPath = javaProjectPath + File.separator + Utils.getMavenProName() + File.separator + Utils.getPomFile();
        if (fileService.isFileExist(pomPath)) {
            String version = getEdpParentVersionInProject(pomPath);
            String nVersion = Utils.getEdpParentVersion();
            if (checkVersion(version, nVersion)) {
                updateEdpParentVersionInProject(pomPath, nVersion);
            }
        }
    }

    protected void updateEdpParentVersionInProject(String path, String version) throws IOException {
        FileOutputStream fileOutputStream = null;
        try {
            Parent parent = model.getParent();
            parent.setVersion(version);
            model.setParent(parent);
            fileOutputStream = new FileOutputStream(path);
            MavenXpp3Writer mavenXpp3Writer = new MavenXpp3Writer();
            mavenXpp3Writer.write(fileOutputStream, model);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (!(null == fileOutputStream)) {
                fileOutputStream.close();
            }
        }
    }

    protected String getEdpParentVersionInProject(String path) throws IOException {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(path);
            MavenXpp3Reader reader = new MavenXpp3Reader();
            model = reader.read(fis);
            return model.getParent().getVersion();
        } catch (XmlPullParserException | IOException e) {
            e.printStackTrace();
        } finally {
            if (!(null == fis)) {
                fis.close();
            }
        }
        return null;
    }

    protected boolean checkVersion(String oldVersion, String newVersion) {
        String[] minerOldVersion = oldVersion.split("\\.");
        String[] minerNewVersion = newVersion.split("\\.");
        for (int i = 0; i < minerNewVersion.length; i++) {
            if (Integer.parseInt(minerNewVersion[i]) > Integer.parseInt(minerOldVersion[i])) {
                return true;
            }
        }
        return false;
    }

    protected boolean isModelExist(String javaProjectPath) {
        if (!fileService.isDirectoryExist(javaProjectPath)) {
            fileService.createDirectory(javaProjectPath);
        }
        String relativeCodePath = commonServiceCore.getProjectPath(javaProjectPath);
        if (relativeCodePath == null) {
            isModelExist = false;
        } else {
            String absoluteCodePath = fileService.getCombinePath(jitContext.getGspProjectpath(), relativeCodePath);
            List<File> list = fileService.getAllFiles(absoluteCodePath);
            for (File file : list) {
                if (file.toString().endsWith(Utils.getPomFile())) {
                    return true;
                }
            }
        }
        return false;
    }

    protected void clearCode(String javaProjectPath) throws IOException {
        /**
         * 由于路径过长，需要优化长度。考虑生成代码兼容问题。判断是否是老工程。老工程将代码继续生成在老工程下
         * 根据api module的名称即可
         */
        String relativeCodePath = commonServiceCore.getProjectPath(javaProjectPath);
        String absoluteCodePath = fileService.getCombinePath(jitContext.getGspProjectpath(), relativeCodePath);
        List<File> allModuleName = fileService.getDirectorys(absoluteCodePath);
        for (File module : allModuleName) {
            if (module.getName().startsWith(jitContext.getGspProjectInfo().getAppCode().toLowerCase())) {
                isOldProject = true;
            }
            if (module.getName().endsWith("api")) {
                if (fileService.isDirectoryExist(module.toString() + File.separator + fixedPath)) {
                    fileService.deleteAllFilesUnderDirectory(module.toString() + File.separator + fixedPath);
                    clearProperties(jitContext, module.getName());
                }
            } else if (module.getName().endsWith("core")) {
                if (fileService.isDirectoryExist(module.toString() + File.separator + fixedPath)) {
                    fileService.deleteAllFilesUnderDirectory(module.toString() + File.separator + fixedPath);
                    clearProperties(jitContext, module.getName());
                }
            }
        }
    }

    protected void installArchetype(String mavenPath) {
        final String absoluteArchetypePath = fileService.getCombinePath(EnvironmentUtil.getServerRTPath(), archetypePath);
        final String absoluteArchetypeTargetPath = fileService.getCombinePath(absoluteArchetypePath, archetypeTarget);
        if (!fileService.isFileExist(absoluteArchetypeTargetPath)) {
            //将程序运行目录中的maven模板安装到本地仓库
            String loStr = "开始：创建Maven模板";
            log.info(loStr);
            LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
            if (mavenUtilsCore.exeMavenCommand(absoluteArchetypePath, mavenPath, "install")) {
                loStr = "完成：创建Maven模板";
                log.info(loStr);
                LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
            } else {
                throw new RuntimeException("Maven模板创建失败，请检查Maven配置");
            }
        }
    }

    private void clearProperties(JitContext context, String module) {
        String factoriesFilePath = context.getGspProjectpath() + "/java/code/" + module + "/src/main/" + JitUtils.getSpringPeopertiesPath();
        if (fileService.isFileExist(factoriesFilePath)) {
            fileService.fileUpdate(factoriesFilePath, "", false);
        }
    }

    protected void generateArchetype(String javaProjectPath, String mavenPath) throws IOException {
        String loStr = "开始：生成maven模板";
        log.info(loStr);
        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
        final String groupId = getGroupId(jitContext);
        final String artifactId = getArtifactId(jitContext);
        String mvnCommand = String.format("archetype:generate -DarchetypeCatalog=local -DarchetypeArtifactId=%s -DarchetypeGroupId=com.inspur.edp -DarchetypeVersion=0.1.3 -DgroupId=%s -DartifactId=%s -Dversion=0.1.0-SNAPSHOT -Dpackage=com.inspur -DinteractiveMode=false", archetypeArtifactId, groupId, artifactId);
        if (mavenUtilsCore.exeMavenCommand(javaProjectPath, mavenPath, mvnCommand)) {
            loStr = "完成：生成maven模板";
            log.info(loStr);
            LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
        } else {
            throw new RuntimeException("生成maven模板失败，请检查Maven配置");
        }
        String javaProPath = javaProjectPath + File.separator + artifactId;
        //重命名生成的目录
        renameDir(javaProjectPath, javaProPath);
    }

    protected void renameDir(String basedir, String pro) throws IOException {
        String finalProname = basedir + File.separator + Utils.getMavenProName();
        if (fileService.isDirectoryExist(finalProname)) {
            String compPath = finalProname + File.separator + "comp";
            if (fileService.isDirectoryExist(compPath)) {
                FileUtils.copyDirectory(new File(compPath), new File(pro + File.separator + "comp"));
            }
            try {
                fileService.deleteAllFilesUnderDirectory(finalProname);
            } catch (Exception e) {

            } finally {
                if (fileService.isDirectoryExist(finalProname)) {
                    FileUtils.copyDirectory(new File(pro), new File(finalProname));
                    fileService.deleteAllFilesUnderDirectory(pro);
                } else {
                    boolean renameResult = fileService.renameDirectory(pro, finalProname);
                    if (!renameResult) {
                        throw new RuntimeException("重命名异常，原目录已存在");
                    }
                    if (fileService.isFileExist(finalProname + File.separator + "pom.xml")) {
                        String loStr = "重命名目录成功！";
                        log.info(loStr);
                        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
                    } else {
                        String loStr = "重命名目录失败！";
                        log.info(loStr);
                        LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
                    }
                }
            }
        } else {
            boolean renameResult = fileService.renameDirectory(pro, finalProname);
            if (!renameResult) {
                throw new RuntimeException("重命名异常，原目录已存在");
            }
            if (fileService.isFileExist(finalProname + File.separator + "pom.xml")) {
                String loStr = "重命名目录成功！";
                log.info(loStr);
                LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
            } else {
                String loStr = "重命名目录失败！";
                log.info(loStr);
                LoggerDisruptorQueue.publishEvent("[INFO] " + loStr, CAFContext.current.getUserId());
            }
        }
    }

    protected String getArtifactId(JitContext jitContext) {
        String appCode = jitContext.getGspProjectInfo().getAppCode().toLowerCase();
        String suCode = jitContext.getGspProjectInfo().getServiceUnitCode().toLowerCase();
        String boCode = jitContext.getGspProjectInfo().getMetadataProjectName().toLowerCase();
        if (boCode.startsWith("bo-")) {
            boCode = boCode.substring(boCode.indexOf("-") + 1);
        }
        String artifactId = String.format("%s-%s-%s", appCode, suCode, boCode);

        return artifactId;
    }

    protected String getGroupId(JitContext jitContext) {
        String groupId;
        String prepareGroupId = jitContext.getGspProjectInfo().getProjectNameSpace().toLowerCase();
        String firstGroupId = "com.";
        if (!prepareGroupId.contains(".")) {
            return firstGroupId + prepareGroupId;
        }
        String[] subGroupId = prepareGroupId.split("\\.");
        groupId = firstGroupId + (subGroupId[0] + "." + subGroupId[1]).toLowerCase();
        return groupId;
    }
}
